#include <utility>
#include <string>

using namespace std;

// 编译器会为 X 和 hasX 合成移动操作
struct X
{
    int i;              // 内置类型可以移动
    std::string s;      // string 定义了自己的移动操作
};

struct hasX
{
    X mem; // X 有合成的移动操作
};

struct Y
{
    // 定义了拷贝构造函数但未定义移动构造函数
    Y(const Y &y) {};
};

struct hasY
{
    hasY() = default;
    hasY(hasY&&) = default;
    Y mem; // hasY 将有一个删除的移动构造函数
};

int main()
{
    X x, x2 = std::move(x);         // 使用合成的移动构造函数
    hasX hx, hx2 = std::move(hx);   // 使用合成的移动构造函数

    // hasY hy, hy2 = std::move(hy);   // 错误：移动构造函数是删除的

    // 一旦一个类定义了拷贝构造函数，那编译器就不会自动为它合成移动构造函数
}